template < class T >
class Goal {
public:
	T *val;
	T best_result;
	q_Bool best_result_is_set;
	T *goal;
	q_Bool (*cmp)(T *, T *, T *);
	double (*result)(const Goal& goal);
	int check_time;
	Goal(T &Qvalue, T &Qgoal, q_Bool (*Qcmp)(T *, T *, T *), double (*Qresult)(const Goal&)) {
		val = &Qvalue;
		goal = &Qgoal;
		cmp = Qcmp;
		result = Qresult;
		best_result_is_set = q_False;
	};
	void check();
	void out();
};

template < class T >
void Goal<T>::check() {
	if (!(best_result_is_set)) {
		best_result_is_set = q_True;
		best_result = (*val);
	}

	if (cmp(val, &best_result, goal)) best_result = (*val);	
}

template < class T >
void Goal<T>::out() {
	cout << (*val) << " --> " << (*goal);
	cout << "  |  ";
	if (best_result_is_set) cout << "Best result : " << best_result;
	else cout << "NO BEST RESULT";
	cout << "  |  Distance: " << result(*this);
	cout << endl;
}

template < class T >
class GoalSet {
public:
	vector < Goal< T > > goals;
	GoalSet() { };
	q_Bool add_goal(Goal<T> goal) {
		goals.push_back(goal);
		return 1;
	};
	void check() {
		for (int t = 0; t < goals.size(); t++)
			goals[t].check();
	};
};
